package com.simple.datax;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.xmlbeans.XmlObject;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.simple.datax.utils.DateUtils;

/**
 * @Title: SimpleMessage.java
 * @Package com.simple.datax
 * @Description: 系统内部使用的保存报文内容的对象
 * @author Paladin Chen
 * @date 2012-12-14 下午6:07:13
 * @version V1.0
 */

public class SimpleMessage implements SimpleObject {
	/**
	 * 
	 */
	private static final long serialVersionUID = 6190388465791761211L;

	private static final Logger logger = LoggerFactory.getLogger(SimpleMessage.class);

	// 连接账号 如EC20303030330@EC0001
	private String account;

	// 报文内容
	private String content;

	// 当前文件名
	private String currentFileName;

	// 报文类型
	private String msgType = "EC";

	// 报文业务类型 如 ECFlow201等等
	private String msgBusiType;

	// 报文格式
	private String msgFormat = "XML";
	// private static Object differentLock = new Object();
	// private static String differentTime = "";

	// 报文编码
	private String encoding = "UTF-8";

	// 时间格式
	private static String FILENAME_FMT = "yyyyMMdd_HHmmss_SSS";

	// 分隔符
	private static String FILENAME_SPLIT = "_";
	private String note;

	// 接收者 EC2323992093
	private String receiver;

	// 接收者节点
	private String receiverNode;

	// 发送者
	private String sender;

	// 发送者节点
	private String senderNode;

	// 报文头中的时间
	private String msgTime;

	// 服务编码
	/**
	 * 定义这个可能有问题！！！ 暂时保留，但不用。 当多个企业使用一个发送通道时，会导致不同公司的信息发送到一家公司。
	 * 
	 * 因为datax系统接收时，使用link URI作为key保持同一个链接的实例。 先来的参数占优。 !!!!!!!!需要在报文中定义，从报文中读出。
	 */
	private String serviceCode = "0";

	// 通讯类型 MSMQ
	private String communType;

	// 通讯连接参数
	private String communParam;

	// 原始报文ID，考虑到原始报文入库的压力，将由接收端程序生成
	private String recvRawMsgid;

	// 报文编号，由报文发送方定义，规则：企业编号（12位）+14位日期（20121220211140）+4位序列号
	private String messageid;

	// 发送的报文编号，由交换平台定义，规则：14位日期+序列号
	private String sentMessageid;

	// 发送的通讯类型
	private String sentCommunType;

	// 发送的通讯参数
	private String sentCommunParam;

	// 发送的报文类型， 报文业务类型一至
	private String sentMsgType = "EC";

	// 发送的报文格式
	private String sentMsgFormat = "XML";

	// 发送的报文编码
	private String sentEncoding = "UTF-8";

	// 消息发出时是否需要更新数据库状态
	private boolean isProcStatus = true;

	// 是否为回复报文
	private boolean isResponse = false;

	// 是否为内部回复报文
	private boolean isIntraResponse = false;

	// 报文是否需要回复
	private boolean needResponse = false;

	// 报文是否压缩
	private boolean isCompress = false;

	// 是不是内部服务发来的报文
	private boolean isIntraMsg = false;

	// 重发报文状态，标示报文出错的位置
	private int resendState = 0;

	// 报文重发的次数
	private int resendCount = 0;

	public int getResendCount() {
		return resendCount;
	}

	public void setResendCount(int resendCount) {
		this.resendCount = resendCount;
	}

	// 解析后的内部对象
	private XmlObject intraDoc;

	/**
	 * 当报文内容字段为null或“”时，读取判断intraDoc对象是否为null，如果不是null， 则返回intraDoc的String格式内容。
	 * 但不改变原content的值。
	 * 
	 * @return
	 */
	public String getContent() {
		if (StringUtils.isBlank(content) && intraDoc != null) {
			//logger.debug("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
			return "<?xml version=\"1.0\" encoding=\"" + sentEncoding + "\"?>" + intraDoc.toString();
		}
		
		//logger.debug("###################################");
		return content;
	}

	public void setContent(String content) {
		//logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
		this.content = content;
	}

	public XmlObject getIntraDoc() {
		return intraDoc;
	}

	public void setIntraDoc(XmlObject intraDoc) {
		this.intraDoc = intraDoc;
	}

	public String getMsgFormat() {
		return msgFormat;
	}

	public void setMsgFormat(String msgFormat) {
		this.msgFormat = msgFormat;
	}

	public String getCommunType() {
		return communType;
	}

	public void setCommunType(String communType) {
		this.communType = communType;
	}

	public String getCommunParam() {
		return communParam;
	}

	public void setCommunParam(String communParam) {
		this.communParam = communParam;
	}

	public String getRecvRawMsgid() {
		return recvRawMsgid;
	}

	public void setRecvRawMsgid(String recvRawMsgid) {
		this.recvRawMsgid = recvRawMsgid;
	}

	public String getMessageid() {
		return messageid;
	}

	public void setMessageid(String messageid) {
		this.messageid = messageid;
	}

	public String getSentMessageid() {
		return sentMessageid;
	}

	public void setSentMessageid(String sentMessageid) {
		this.sentMessageid = sentMessageid;
	}

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public String getCurrentFileName() {
		return currentFileName;
	}

	public void setCurrentFileName(String currentFileName) {
		this.currentFileName = currentFileName;
	}

	public String getDifferentTime() {
		String result = "now_err";

		try {
			result = DateUtils.getTimeStamp(FILENAME_FMT);
		} catch (Exception e) {
			logger.debug("Format Date error:", e);
		}

		return result;
	}

	public String getEncoding() {
		return encoding;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	}

	public boolean isProcStatus() {
		return isProcStatus;
	}

	public void setProcStatus(boolean isProcStatus) {
		this.isProcStatus = isProcStatus;
	}

	public String getReceiver() {
		return receiver;
	}

	public void setReceiver(String receiver) {
		this.receiver = receiver;
	}

	public String getSender() {
		return sender;
	}

	public void setSender(String sender) {
		this.sender = sender;
	}

	public String getFileName() {
		return getFileName(true);
	}

	public String getFileName(boolean isSend) {
		StringBuilder builder = new StringBuilder();
		if (isSend) {
			if (StringUtils.isBlank(sentCommunType)) {
				builder.append(this.msgBusiType);
			} else {
				builder.append(sentCommunType);
				builder.append(FILENAME_SPLIT);
				builder.append(msgBusiType);
			}
		} else {
			if (StringUtils.isBlank(communType)) {
				builder.append(this.msgBusiType);
			} else {
				builder.append(communType);
				builder.append(FILENAME_SPLIT);
				builder.append(msgBusiType);
			}
		}
		builder.append(FILENAME_SPLIT);
		if (!StringUtils.isBlank(messageid)) {
			builder.append(messageid);
		}

		builder.append(FILENAME_SPLIT);
		if (!StringUtils.isBlank(sender)) {
			builder.append("(");
			builder.append(sender);
			builder.append("@");
			builder.append(senderNode);
			builder.append(")");
		}

		builder.append(FILENAME_SPLIT);
		if (!StringUtils.isBlank(receiver)) {
			builder.append("(");
			builder.append(receiver);
			builder.append("@");
			builder.append(receiverNode);
			builder.append(")");
		}
		builder.append(FILENAME_SPLIT);
		builder.append(DateUtils.getTimeStamp("yyyyMMddHHmmssSSS"));
		return builder.toString();
	}

	public String getOriFileName() {
		return getOriFileName(true);
	}

	public String getOriFileName(boolean isSend) {
		StringBuilder builder = new StringBuilder();
		if (isSend) {
			if (StringUtils.isBlank(sentCommunType)) {
				builder.append(this.recvRawMsgid);
			} else {
				builder.append(sentCommunType);
				builder.append(FILENAME_SPLIT);
				builder.append(recvRawMsgid);
			}
		} else {
			if (StringUtils.isBlank(communType)) {
				builder.append(this.recvRawMsgid);
			} else {
				builder.append(communType);
				builder.append(FILENAME_SPLIT);
				builder.append(recvRawMsgid);
			}
		}

		// 区别回复报文，对于一条报文，可能有多条发送报文出去，回复报文的messageid为解析的原始报文id，而sentMessageid是新生产的id
		if (!StringUtils.isBlank(sentMessageid)) {
			builder.append(FILENAME_SPLIT);
			builder.append(sentMessageid);
		}
		return builder.toString();
	}

	public String getMsgType() {
		return msgType;
	}

	public void setMsgType(String msgType) {
		this.msgType = msgType;
	}

	public String getMsgBusiType() {
		return msgBusiType;
	}

	public void setMsgBusiType(String msgBusiType) {
		this.msgBusiType = msgBusiType;
	}

	public String getSentCommunType() {
		return sentCommunType;
	}

	public void setSentCommunType(String sentCommunType) {
		this.sentCommunType = sentCommunType;
	}

	public String getSentCommunParam() {
		return sentCommunParam;
	}

	public void setSentCommunParam(String sentCommunParam) {
		this.sentCommunParam = sentCommunParam;
	}

	public String getSentMsgType() {
		return sentMsgType;
	}

	public void setSentMsgType(String sentMsgType) {
		this.sentMsgType = sentMsgType;
	}

	public String getSentMsgFormat() {
		return sentMsgFormat;
	}

	public void setSentMsgFormat(String sentMsgFormat) {
		this.sentMsgFormat = sentMsgFormat;
	}

	public String getSentEncoding() {
		return sentEncoding;
	}

	public void setSentEncoding(String sentEncoding) {
		this.sentEncoding = sentEncoding;
	}

	public String getServiceCode() {
		return serviceCode;
	}

	public void setServiceCode(String serviceCode) {
		this.serviceCode = serviceCode;
	}

	public String getReceiverNode() {
		return receiverNode;
	}

	public void setReceiverNode(String receiverNode) {
		this.receiverNode = receiverNode;
	}

	public String getSenderNode() {
		return senderNode;
	}

	public void setSenderNode(String senderNode) {
		this.senderNode = senderNode;
	}

	public boolean isResponse() {
		return isResponse;
	}

	public void setResponse(boolean isResponse) {
		this.isResponse = isResponse;
	}

	public boolean isCompress() {
		return isCompress;
	}

	public void setCompress(boolean isCompress) {
		this.isCompress = isCompress;
	}

	public boolean isNeedResponse() {
		return needResponse;
	}

	public void setNeedResponse(boolean needResponse) {
		this.needResponse = needResponse;
	}

	public String getMsgTime() {
		return msgTime;
	}

	public void setMsgTime(String msgTime) {
		this.msgTime = msgTime;
	}

	public boolean isIntraMsg() {
		return isIntraMsg;
	}

	public void setIntraMsg(boolean isIntraMsg) {
		this.isIntraMsg = isIntraMsg;
	}

	public int getResendState() {
		return resendState;
	}

	public void setResendState(int resendState) {
		this.resendState = resendState;
	}

	public SimpleMessage() {

	}

	public SimpleMessage(String encoding) {
		this.encoding = encoding;
	}

	public boolean isIntraResponse() {
		return isIntraResponse;
	}

	public void setIntraResponse(boolean isIntraResponse) {
		this.isIntraResponse = isIntraResponse;
	}

	public String toString() {
		return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
	}

	public String toLog() {
		return "recvRawMsgid:(" + recvRawMsgid + ") messageid:(" + messageid + ") resendstate:(" + resendState
				+ ") intraMessage:(" + isIntraMsg + ") ";
	}
}
